﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using SCRUM.Core.BusinessObjects;
using SCRUM.Core.DAO;

/// <summary>
/// User control for adding comments to widget. Required are TypeOfEntity and EntityID. 
/// Comments are shown as list. They can be collapsed or expanded.  
/// </summary>
public partial class User_Controls_Inputs_CommentPanel : System.Web.UI.UserControl
{
    /// <summary>
    /// String definition of type of entity. F.e. task, bli, ...
    /// </summary>
    public string TypeOfEntity
    {
        get
        {
            return this.type;
        }
        set
        {
            HttpContext.Current.Session["TypeOfEntity" + this.ID] = value;
            this.type = value;
        }
    }
    /// <summary>
    /// ID of entity to display comments for
    /// </summary>
    public int EntityID
    {
        get
        {
            return this.entityID;
        }
        set
        {
            HttpContext.Current.Session["EntityNodeID" + this.ID] = value;
            this.entityID = value;
        }
    }

    /// <summary>
    /// Private representation of entity's ID 
    /// </summary>
    private int entityID = -1;

    /// <summary>
    /// Privagte representation of type of entity
    /// </summary>
    private string type;

    /// <summary>
    /// Represents all threads connected to entity
    /// </summary>
    private List<Thread> allThreads { get; set; }

    /// <summary>
    /// Initial method
    /// </summary>
    /// <param name="sender">Sender</param>
    /// <param name="e">Parameters</param>
    protected void Page_Load(object sender, EventArgs e)
    {
        DeleteComment.Visible = false;
        Details.Visible = false;
        if (entityID != -1)
        {
            
        }
        //threadsData.Visible = true;
        if (threadsData.SelectedNode == null)
        {
        }
    }

    /// <summary>
    /// Main method to populate tree that represents threads and comments
    /// </summary>
    /// <param name="sender">Sender</param>
    /// <param name="e">Parameters</param>
    protected void Node_Populate(object sender, TreeNodeEventArgs e)
    {
        {
            if (e.Node.ChildNodes.Count == 0)
            {
                switch (e.Node.Depth)
                {
                    case 0:
                            fillComments(e.Node);
                            break;
                }
            }
        }
    }

    /// <summary>
    /// Method that creates nodes in tree for threads 
    /// </summary>
    /// <param name="node">Parent node</param>
    private void fillThreads(TreeNode node)
    {
        setEntityAndType();

        allThreads = DAOComment.GetAllThreadsForEntity(entityID, type);
        foreach (Thread row in allThreads)
        {
            createSubNode(node, row.Name, row.ID.ToString(), true);
        }
    }

    /// <summary>
    /// Method to fill required paramethers
    /// </summary>
    private void setEntityAndType()
    {
        if (TypeOfEntity != null)
        {
            type = TypeOfEntity;
        }
        else
            if (HttpContext.Current.Session["TypeOfEntity" + this.ID] != null)
            {
                type = HttpContext.Current.Session["TypeOfEntity" + this.ID].ToString();
            }
            else
            {
                throw new Exception("Type pf entity not set");
            }

        if (EntityID != null)
        {
            entityID = EntityID;
        }
        else
            if (HttpContext.Current.Session["EntityNodeID" + this.ID] != null)
            {
                entityID = System.Convert.ToInt32(HttpContext.Current.Session["EntityNodeID" + this.ID]);
            }
            else
            {
                throw new Exception("Type pf entity not set");
            } 
    }

    /// <summary>
    /// Method that creates nodes in tree for comments that are directly in threads 
    /// </summary>
    /// <param name="node">Parent node</param>
    private void fillCommentsForThread(TreeNode node)
    {
        foreach (Comment row in DAOComment.GetAllCommentsForThread(System.Convert.ToInt32(node.Value)))
        {
            createSubNode(node, row.ToString(), row.ID.ToString(), true);
        }
    }

    /// <summary>
    /// Method that creates nodes in tree for comments that are comments on comments 
    /// </summary>
    /// <param name="node">Parent node</param>
    private void fillComments(TreeNode node)
    {
        foreach (Comment row in DAOComment.GetCommentsForEntity(entityID, type))
        {
            createSubNode(node, row.ToString(), row.ID.ToString(), true);
        }
    }

    /// <summary>
    /// Creates node with specific values and adds it to tree
    /// </summary>
    /// <param name="parent">Parent node</param>
    /// <param name="name">Displayed text</param>
    /// <param name="id">Value of node</param>
    /// <param name="isThread">if thread than display in specific way</param>
    /// <returns>Creaated node</returns>
    private TreeNode createSubNode(TreeNode parent, String name, String id, bool isThread)
    {
        if (isThread)     
        {
            if (name.Length >= 30)
            {
                name = name.Substring(0, 30);
            }
        }

        TreeNode newNode = new TreeNode(name, id);
        //newNode.PopulateOnDemand = true;
        newNode.SelectAction = TreeNodeSelectAction.Select;
        parent.ChildNodes.Add(newNode);
        newNode.Expand();
        return newNode;
    }

    /// <summary>
    /// REfreshes whole user control, reloads tree data
    /// </summary>
    public void Refresh()
    {
        threadsData.Nodes[0].ChildNodes.Clear();
        fillComments(threadsData.Nodes[0]);
        threadsData.DataBind();
        threadsData.Nodes[0].Collapse();
    }

    /// <summary>
    /// Handle click on data in tree and shows details
    /// </summary>
    /// <param name="sender">Sender</param>
    /// <param name="e">Param</param>
    protected void threadsData_SelectedNodeChanged(object sender, EventArgs e)
    {
        if (threadsData.SelectedNode == null)
        {
            return;
        }
        CreateNew.Visible = true;
        if (threadsData.SelectedNode.Depth == 0)
        {
            
            CreateNew.Text = "Create new comment";
            Details.Visible = false;
            threadsData.Visible = true;
            NewText.Text = "";
            CreateNew.Visible = true;
            DeleteComment.Visible = false;
        }
        else if (threadsData.SelectedNode.Depth == 1)
        {
        //    Details.Visible = true;
        //    threadsData.Visible = true;
        //    ToThread.Visible = false;
        //    Thread th = DAOComment.GetThreadByID(System.Convert.ToInt32(threadsData.SelectedNode.Value));
        //    CreateNew.Text = "Create new comment";
        //    NewText.Text = th.Name;
        //    DeleteComment.Visible = true;
        //}
        //else 
        //{
            Details.Visible = true;
            threadsData.Visible = true;
            setEntityAndType();
            Comment co = DAOComment.GetCommentByID(System.Convert.ToInt32(threadsData.SelectedNode.Value));
            //CreateNew.Text = "Create new comment";
            NewText.Text = co.Text;
            DeleteComment.Visible = true;
        }
        AddComment.Visible = false;
        this.Visible = true;
        threadsData.ExpandAll();
    }
    /// <summary>
    /// Handles creation of new entity
    /// </summary>
    /// <param name="sender">Sender</param>
    /// <param name="e">Parameters</param>
    protected void CreateNew_Click(object sender, EventArgs e)
    {
        NewText.Text = "";
        DeleteComment.Visible = false;
        AddComment.Visible = true;
        Details.Visible = true;
    }
    /// <summary>
    /// Handles creation of new comment
    /// </summary>
    /// <param name="sender">Sender</param>
    /// <param name="e">Parameter</param>
    protected void AddComment_Click(object sender, EventArgs e)
    {
        //if (threadsData.SelectedNode.Depth == 0)
        //{
        //    setEntityAndType();
        //    Thread thread = new Thread(0, NewText.Text, type, entityID);
        //    Thread newTh = DAOComment.CreateNewThread(thread);
        //    threadsData.SelectedNode.Expand();
        //    //n = createSubNode(threadsData.SelectedNode, newTh.Name, newTh.ID.ToString(), true);
        //    TreeNode no = threadsData.SelectedNode.Parent;
        //    threadsData.SelectedNode.Parent.ChildNodes.Clear();

        //    Node_Populate(new Object(), new TreeNodeEventArgs(no));
        //}
        //else 
        //{ 
            //TreeNode node = threadsData.SelectedNode;
            //while( node.Depth!= 1)
            //{
            //    node = node.Parent;
            //}

            User user = SCRUM.Core.MembershipProviders.MembershipProviderFactory.MembershipProvider.GetUser();
            
            Thread thr = new Thread(0, "tmp", type, entityID);
            thr = DAOComment.CreateNewThread(thr);
            Comment comm = new Comment(0, NewText.Text, DateTime.Today, user.Login, thr);
            int inComm = -1;
            //if (threadsData.SelectedNode.Depth > 1) {
            //    inComm = System.Convert.ToInt32(threadsData.SelectedNode.Value);
            //}
            Comment c = DAOComment.CreateNewComment(comm, inComm);
            //threadsData.SelectedNode.Expand();
            TreeNode n = createSubNode(threadsData.Nodes[0], c.ToString(), c.ID.ToString(), false);
            CreateNew.Visible = true;
            //TreeNode no = threadsData.SelectedNode.Parent;
            //threadsData.SelectedNode.Parent.ChildNodes.Clear();
            
            //Node_Populate(new Object(), new TreeNodeEventArgs(no));
        //}
       //threadsData.DataBind();
    }

    /// <summary>
    /// Handles deletion of comment
    /// </summary>
    /// <param name="sender">Sender</param>
    /// <param name="e">Parameters</param>
    protected void DeleteComment_Click(object sender, EventArgs e)
    {
        if (threadsData.SelectedNode.Depth == 0)
        {
            return;
        }
        else 
        {
            Comment com = DAOComment.GetCommentByID(System.Convert.ToInt32(threadsData.SelectedNode.Value));
            DAOComment.DeleteComment(com);
            DAOComment.DeleteThread(com.InThread);
            threadsData.SelectedNode.Parent.ChildNodes.Remove(threadsData.SelectedNode);

        }
        threadsData.DataBind();
    }

    /// <summary>
    /// Deletes whole subtree for specific node
    /// </summary>
    /// <param name="node">Node to delete subtree for</param>
    private void deleteSubtree(TreeNode node)
    {
        int id = -1;
        while (node.ChildNodes.Count != 0)
        {
            for (int i = 0; i < node.ChildNodes.Count; i++)
            {
                deleteSubtree(node.ChildNodes[i]);
            }
        }
        //if(id !=  System.Convert.ToInt32(node.Value))
        //{
            if (node.Depth == 1)
            {
                Thread th = new Thread();
                th.ID = System.Convert.ToInt32(node.Value);
                DAOComment.DeleteThread(th);
                node.Parent.ChildNodes.Remove(node);
            }
            else
            {
                Comment com = new Comment();
                com.ID = System.Convert.ToInt32(node.Value);
                DAOComment.DeleteComment(com);
                node.Parent.ChildNodes.Remove(node);

           // }
        }
    }

    /// <summary>
    /// Handles selection event in tree, displayes detail of comment
    /// </summary>
    /// <param name="sender">Sender</param>
    /// <param name="e">Parameters</param>
    protected void ListView_SelectedIndexChanged(object sender, EventArgs e)
    {
            Details.Visible = true;
            threadsData.Visible = true;
            setEntityAndType();
            Comment co = DAOComment.GetCommentByID(System.Convert.ToInt32(threadsData.SelectedNode.Value));
            //CreateNew.Text = "Create new comment";
            NewText.Text = co.Text;
            DeleteComment.Visible = true;
        
        AddComment.Visible = false;
    }
}
